package org.javahispano.javacup.tacticas_aceptadas.jcrosas.chuky.futbolista.habilidad;

import java.util.ArrayList;

import org.javahispano.javacup.tacticas_aceptadas.jcrosas.chuky.futbolista.Futbolista;
import org.javahispano.javacup.tacticas_aceptadas.jcrosas.chuky.util.Balon;
import org.javahispano.javacup.tacticas_aceptadas.jcrosas.chuky.util.PaseAlto;
import org.javahispano.javacup.tacticas_aceptadas.jcrosas.chuky.util.PaseJugada;
import org.javahispano.javacup.tacticas_aceptadas.jcrosas.chuky.util.PosicionCampo;
import org.javahispano.javacup.tacticas_aceptadas.jcrosas.chuky.util.PosicionFutura;
import org.javahispano.javacup.tacticas_aceptadas.jcrosas.chuky.futbolista.FutbolistaBase;
import org.javahispano.javacup.tacticas_aceptadas.jcrosas.chuky.futbolista.habilidad.PaseOfensivo.EfectividadPase;
import org.javahispano.javacup.tacticas_aceptadas.jcrosas.chuky.futbolista.habilidad.PaseOfensivo.ExactitudPase;

/**
 * @author Joan Crosas
 *
 */
public class JugadaMortal extends JugadaMortalPreparacion {

	protected double errorMax;

	public JugadaMortal( Futbolista futbolista ) {
		super( futbolista );
		errorMax = FutbolistaBase.JUGADA_MORTAL_ERROR_MAX;
	}

	@Override
	public boolean ejecutar() {
		if( futbolista.getIteracionesParaRematar() == 0 && 
				futbolista.balonEncima( futbolista.getVisionPartido().getBalon() ) &&
				isJugadaPosible( FutbolistaBase.JUGADA_MORTAL_POSICION_BALON, FutbolistaBase.JUGADA_MORTAL_TIEMPO_INICIO ) ) {
			
			PaseJugada paseJugadaMortal = evaluarJugada( FutbolistaBase.JUGADA_MORTAL_POSICION_BALON );
			
			if( paseJugadaMortal != null ) {
				int tiempoJugada = paseJugadaMortal.getPosicionJugadaBalon().getTiempo() + 3; // regalo 3 iteraciones
				if( isJugadaPosible( paseJugadaMortal.getPosicionJugadaBalon(), tiempoJugada ) ) {
					iniciarJugada( paseJugadaMortal.getPosicionJugadaBalon(), paseJugadaMortal );
					
					return true;
				}
				
			}
		}
		return false;
	}
	
	protected PaseJugada evaluarJugada( PosicionCampo posicionJugada ) {
		PosicionCampo posicionInicial = futbolista.getVisionPartido().getBalon().getPosicionBalon();
		double anguloBase = posicionInicial.angulo( posicionJugada );
		
		ArrayList<PaseJugada> pases = new ArrayList<PaseJugada>();
		PaseJugada paseJugada;
		
		paseJugada = obtenerPaseJugada( posicionJugada, anguloBase, 1.0, FutbolistaBase.JUGADA_MORTAL_ANGULO_VERTICAL );
		if( paseJugada.getEfectividadPase() == EfectividadPase.RECIBIDO ) {
			return paseJugada;
		}
		pases.add( paseJugada );
		
		paseJugada = obtenerPaseJugada( posicionJugada, anguloBase, 0.8, FutbolistaBase.JUGADA_MORTAL_ANGULO_VERTICAL );
		if( paseJugada.getEfectividadPase() == EfectividadPase.RECIBIDO ) {
			return paseJugada;
		}
		pases.add( paseJugada );
		
		paseJugada = obtenerPaseJugada( posicionJugada, anguloBase, 0.6, FutbolistaBase.JUGADA_MORTAL_ANGULO_VERTICAL );
		if( paseJugada.getEfectividadPase() == EfectividadPase.RECIBIDO ) {
			return paseJugada;
		}
		pases.add( paseJugada );
		
		for( int j = 0; j < 16; j++) {
			PaseAlto paseAltoCorto = buscarPaseJugada( pases, ExactitudPase.CORTO );
			PaseAlto paseAltoLargo = buscarPaseJugada( pases, ExactitudPase.LARGO );
			
			double potencia = 1;
			double anguloVertical = FutbolistaBase.JUGADA_MORTAL_ANGULO_VERTICAL;
			
			if( paseAltoCorto != null && paseAltoLargo != null ) {
				potencia = (paseAltoCorto.getPotencia() + paseAltoLargo.getPotencia()) / 2;
				anguloVertical = (paseAltoCorto.getAnguloVertical() + paseAltoLargo.getAnguloVertical()) / 2;
				
				paseJugada = obtenerPaseJugada( posicionJugada, anguloBase, potencia, anguloVertical );
				if( paseJugada.getEfectividadPase() == EfectividadPase.RECIBIDO ) {
					return paseJugada;
				}
				pases.add( paseJugada );
				
			} else if( paseAltoCorto != null ) {
				potencia = paseAltoCorto.getPotencia();
				anguloVertical = paseAltoCorto.getAnguloVertical();
				
			} else if( paseAltoLargo != null ) {
				potencia = paseAltoLargo.getPotencia();
				anguloVertical = paseAltoLargo.getAnguloVertical();
				
			} else {
				break;
			}
			
			paseJugada = obtenerPaseJugada( posicionJugada, anguloBase, getMitadAlta( potencia, 1.0 ), getMitadAlta( anguloVertical, FutbolistaBase.JUGADA_MORTAL_ANGULO_VERTICAL_MAX ) );
			if( paseJugada.getEfectividadPase() == EfectividadPase.RECIBIDO ) {
				return paseJugada;
			}
			pases.add( paseJugada );
			
			paseJugada = obtenerPaseJugada( posicionJugada, anguloBase, potencia, getMitadAlta( anguloVertical, FutbolistaBase.JUGADA_MORTAL_ANGULO_VERTICAL_MAX ) );
			if( paseJugada.getEfectividadPase() == EfectividadPase.RECIBIDO ) {
				return paseJugada;
			}
			pases.add( paseJugada );
			
			paseJugada = obtenerPaseJugada( posicionJugada, anguloBase, potencia, getMitad( anguloVertical, FutbolistaBase.JUGADA_MORTAL_ANGULO_VERTICAL_MIN ) );
			if( paseJugada.getEfectividadPase() == EfectividadPase.RECIBIDO ) {
				return paseJugada;
			}
			pases.add( paseJugada );
			
			paseJugada = obtenerPaseJugada( posicionJugada, anguloBase, getMitadAlta( potencia, 1.0 ), getMitad( anguloVertical, FutbolistaBase.JUGADA_MORTAL_ANGULO_VERTICAL_MIN ) );
			if( paseJugada.getEfectividadPase() == EfectividadPase.RECIBIDO ) {
				return paseJugada;
			}
			pases.add( paseJugada );
			
			paseJugada = obtenerPaseJugada( posicionJugada, anguloBase, getMitad( potencia, 0.6 ), getMitad( anguloVertical, FutbolistaBase.JUGADA_MORTAL_ANGULO_VERTICAL_MIN ) );
			if( paseJugada.getEfectividadPase() == EfectividadPase.RECIBIDO ) {
				return paseJugada;
			}
			pases.add( paseJugada );
			
			paseJugada = obtenerPaseJugada( posicionJugada, anguloBase, getMitad( potencia, 0.6 ), anguloVertical );
			if( paseJugada.getEfectividadPase() == EfectividadPase.RECIBIDO ) {
				return paseJugada;
			}
			pases.add( paseJugada );
			
			paseJugada = obtenerPaseJugada( posicionJugada, anguloBase, getMitad( potencia, 0.6 ), getMitadAlta( anguloVertical, FutbolistaBase.JUGADA_MORTAL_ANGULO_VERTICAL_MAX ) );
			if( paseJugada.getEfectividadPase() == EfectividadPase.RECIBIDO ) {
				return paseJugada;
			}
			pases.add( paseJugada );
			
		}
		return null;
		
	}
	
	private PaseJugada obtenerPaseJugada( PosicionCampo posicionJugada, double angulo, double potencia, double anguloVertical ) {
		double velocidadInicial = potencia * futbolista.getRemate();
		PosicionCampo posicionInicial = futbolista.getVisionPartido().getBalon().getPosicionBalon();
		Balon balon = new Balon( posicionInicial, angulo, velocidadInicial, anguloVertical );
		
		PaseJugada paseJugada = new PaseJugada();
		paseJugada.setBalon( balon );
		paseJugada.setAnguloVertical( anguloVertical );
		paseJugada.setPotencia( potencia );
		paseJugada.setAnguloRemate( angulo );
		
		// exactitud pase
		PosicionFutura posicionBalonJugada = evaluarExactitudJugadaMortal( balon, FutbolistaBase.JUGADA_MORTAL_ALTURA );
		if( posicionInicial.distancia( posicionBalonJugada ) > posicionInicial.distancia( posicionJugada ) ) {
			paseJugada.setExactitudPase( ExactitudPase.LARGO );
		} else {
			paseJugada.setExactitudPase( ExactitudPase.CORTO );
		}
		paseJugada.setPosicionJugadaBalon( posicionBalonJugada );
		
		// efectividad pase
		if( evaluarEfectividadJugadaMortal( paseJugada, posicionJugada, FutbolistaBase.JUGADA_MORTAL_ALTURA, errorMax ) ) {
			paseJugada.setEfectividadPase( EfectividadPase.RECIBIDO );
		} else {
			paseJugada.setEfectividadPase( EfectividadPase.PERDIDO );
		}
		
		return paseJugada;
	}
	
	private PaseAlto buscarPaseJugada( ArrayList<PaseJugada> pases, ExactitudPase exactitud ) {
		PaseAlto paseAlto = null;
		for( int i = 0; i < pases.size(); i++ ) {
			if( pases.get(i).getExactitudPase() == exactitud ) {
				if( paseAlto == null ) {
					paseAlto = pases.get(i);
					
				} else if( paseAlto != null && pases.get(i).getDistanciaExactitud() < paseAlto.getDistanciaExactitud() ) {
					paseAlto = pases.get(i);
				}
			}
		}
		if( paseAlto != null ) {
			pases.remove( paseAlto );
		}
		return paseAlto;
	}

}
